/**
 *  请求类
 */

#import "DCRequest.h"
#import <AFNetworking/AFNetworking.h>


#define kDCRequestTimeOutInterval   30.0


@interface DCRequest(){
    NSString *_baseUrl;
    NSString *_path;
    DCRequestType _requestType;
    AFHTTPSessionManager *_manger;
}

/**请求参数字典*/
@property (nonatomic, retain) NSMutableDictionary *dicParams;

@end

@implementation DCRequest

/**
 *  懒加载
 */
- (NSMutableDictionary *)dicParams{
    if (!_dicParams) {
        _dicParams = [NSMutableDictionary dictionary];
    }
    return _dicParams;
}


/**
 *  单例模式
 *
 */

static DCRequest *_request;


+ (instancetype)shareDCRequest{
    //谓词
    static dispatch_once_t predicate;
    
    //    这里的代码只执行一次
    dispatch_once(&predicate,^{
        _request = [[DCRequest alloc] init];
    });
    
    return _request;
}

/**
 *  注册请求
 *
 *  @param baseUrl     请求链接URL
 *  @param path        请求路径
 *  @param requestType 请求类型
 *
 *  @return 返回注册的请求
 */
- (id)initWithBaseURL:(NSString *)baseUrl path:(NSString *)path requestType:(DCRequestType)requestType;{
    self = [super init];
    if (self) {
        _baseUrl = baseUrl;
        _path = path;
        _requestType = requestType;
    }
    return self;
}

/**
 *  请求参数
 *
 *  @param param 参数值
 *  @param key   参数名
 */
- (void)setParam:(NSObject *)param forKey:(NSString *)key{
    [self.dicParams setObject:param forKey:key];
}

/**
 *  获取参数值
 *
 *  @param key 参数名
 *
 *  @return 参数值
 */
- (NSObject *)getParamForKey:(NSString *)key{
    return [self.dicParams objectForKey:key];
}

/**
 *  根据参数名移除参数
 *
 *  @param key 参数名
 */
- (void)removeParamForKey:(NSString *)key{
    [self.dicParams removeObjectForKey:key];
}

/**
 *  移除所有参数
 */
- (void)removeAllParams{
    [self.dicParams removeAllObjects];
}

/**
 *  取消请求
 */
- (void)cancelRequest{
    [_manger.operationQueue cancelAllOperations];
}



#pragma mark ------请求
/**
 *  请求正常并返回成功结果
 *
 *  @param menuArray   目录参数数组(用到目录参数的调用)
 *  @param callBack 请求结果
 */
- (void)callWithMenu:(nullable NSMutableArray *)menuArray callBack:(nullable void (^)(DCResponse * _Nullable response))callBack{
    //组合请求URL
    NSString *requestUrl = [_baseUrl stringByAppendingString:_path];
    //添加目录参数
    if (![menuArray isKindOfClass:[NSNull class]]) {
        if (menuArray.count != 0) {
            for (int i = 0; i < menuArray.count;i ++) {
                NSString *str = [NSString stringWithFormat:@"/%@",[menuArray objectAtIndex:i]];
                requestUrl = [requestUrl stringByAppendingString:str];
            }
        }
    }
    
    NSLog(@"开始请求:%@,参数:%@",requestUrl,self.dicParams);
    
    [self requestUrl:requestUrl parameter:self.dicParams requestType:_requestType success:^(NSMutableDictionary *dict) {
        DCResponse *response = [[DCResponse alloc] init];
        response.data = dict;
        callBack(response);
    } error:^(NSString *errorMsg) {
        NSLog(@"系统失败信息：%@",errorMsg);
    }];
}

/**
 *  请求正常单系统返回错误信息,自己init的时候调用
 *
 *  @param menuArray   目录参数数组(用到目录参数的调用)
 *  @param callBack 请求结果
 *  @param error    系统错误提示
 *
 */
- (void)callWithMenu:(nullable NSMutableArray *)menuArray callBack:(nullable void (^)(DCResponse * _Nullable response))callBack error:(nullable void (^)(NSString * _Nullable errorMsg))error{
    //组合请求URL
    NSString *requestUrl = [_baseUrl stringByAppendingString:_path];
    //添加目录参数
    if (![menuArray isKindOfClass:[NSNull class]]) {
        if (menuArray.count != 0) {
            for (int i = 0; i < menuArray.count;i ++) {
                NSString *str = [NSString stringWithFormat:@"/%@",[menuArray objectAtIndex:i]];
                requestUrl = [requestUrl stringByAppendingString:str];
            }
        }
    }
    
    NSLog(@"开始请求:%@,参数:%@",requestUrl,self.dicParams);
    
    [self requestUrl:requestUrl parameter:self.dicParams requestType:_requestType success:^(NSMutableDictionary *dict) {
        DCResponse *response = [[DCResponse alloc] init];
        response.data = dict;
        callBack(response);
    } error:^(NSString *errorMsg) {
        NSLog(@"系统失败信息：%@",errorMsg);
        error(errorMsg);
    }];
}

/**
 *  请求正常并返回成功结果，使用单例的时候调用
 *
 *  @param baseUrl             请求链接URL
 *  @param path                请求路径
 *  @param menuArray           目录参数数组(用到目录参数的调用)
 *  @param requestType         请求类型
 *  @param parameterDictionary 请求参数
 *  @param callBack            请求结果
 */
- (void)callWithWithBaseURL:(nullable NSString *)baseUrl path:(nullable NSString *)path menu:(nullable NSMutableArray *)menuArray requestType:(DCRequestType)requestType parameter:(nullable NSMutableDictionary *)parameterDictionary callBack:(nullable void (^)(DCResponse * _Nullable response))callBack{
    //组合请求URL
    NSString *requestUrl = [baseUrl stringByAppendingString:path];
    //添加目录参数
    if (![menuArray isKindOfClass:[NSNull class]]) {
        if (menuArray.count != 0) {
            for (int i = 0; i < menuArray.count;i ++) {
                NSString *str = [NSString stringWithFormat:@"/%@",[menuArray objectAtIndex:i]];
                requestUrl = [requestUrl stringByAppendingString:str];
            }
        }
    }
    
    NSLog(@"开始请求:%@,参数:%@",requestUrl,parameterDictionary);
    
    [self requestUrl:requestUrl parameter:parameterDictionary requestType:requestType success:^(NSMutableDictionary *dict) {
        DCResponse *response = [[DCResponse alloc] init];
        response.data = dict;
        callBack(response);
    } error:^(NSString *errorMsg) {
        NSLog(@"系统失败信息：%@",errorMsg);
    }];
}

/**
 *  请求失败，使用单例的时候调用
 *
 *  @param baseUrl             请求链接URL
 *  @param path                请求路径
 *  @param menuArray           目录参数数组(用到目录参数的调用)
 *  @param requestType         请求类型
 *  @param parameterDictionary 请求参数
 *  @param callBack            请求结果
 *  @param error               系统错误提示
 */
- (void)callWithWithBaseURL:(nullable NSString *)baseUrl path:(nullable NSString *)path menu:(nullable NSMutableArray *)menuArray requestType:(DCRequestType)requestType parameter:(nullable NSMutableDictionary *)parameterDictionary callBack:(nullable void (^)(DCResponse * _Nullable response))callBack error:(nullable void (^)(NSString * _Nullable errorMsg))error{
    //组合请求URL
    NSString *requestUrl = [baseUrl stringByAppendingString:path];
    //添加目录参数
    if (![menuArray isKindOfClass:[NSNull class]]) {
        if (menuArray.count != 0) {
            for (int i = 0; i < menuArray.count;i ++) {
                NSString *str = [NSString stringWithFormat:@"/%@",[menuArray objectAtIndex:i]];
                requestUrl = [requestUrl stringByAppendingString:str];
            }
        }
    }
    
    NSLog(@"开始请求:%@,参数:%@",requestUrl,parameterDictionary);
    
    [self requestUrl:requestUrl parameter:parameterDictionary requestType:requestType success:^(NSMutableDictionary *dict) {
        DCResponse *response = [[DCResponse alloc] init];
        response.data = dict;
        callBack(response);
    } error:^(NSString *errorMsg) {
        NSLog(@"系统失败信息：%@",errorMsg);
        error(errorMsg);
    }];
    
}



/**
 *  根据请求类型选择请求方法
 *
 *  @param url         请求地址
 *  @param parameter   请求参数
 *  @param requestType 请求类型
 *  @param success     成功回调
 *  @param error       失败信息
 */
- (void)requestUrl:(NSString *)url parameter:(id)parameter requestType:(DCRequestType)requestType success:(void (^)(NSMutableDictionary *dict))success error:(void (^)(NSString *errorMsg))error{
    
    switch (_requestType) {
        case DCRequestTypeGet:{
            [self GET:url parameter:parameter success:^(NSMutableDictionary *dict) {
                success(dict);
            } error:^(NSString *errorMsg) {
                error(errorMsg);
            }];
        }
            break;
        case DCRequestTypePost:{
            [self POST:url parameter:parameter success:^(NSMutableDictionary *dict) {
                success(dict);
            } error:^(NSString *errorMsg) {
                error(errorMsg);
            }];
        }
            break;
        case DCRequestTypePut:{
            [self PUT:url parameter:parameter success:^(NSMutableDictionary *dict) {
                success(dict);
            } error:^(NSString *errorMsg) {
                error(errorMsg);
            }];
        }
            break;
        case DCRequestTypeDelete:{
            [self DELETE:url parameter:parameter success:^(NSMutableDictionary *dict) {
                success(dict);
            } error:^(NSString *errorMsg) {
                error(errorMsg);
            }];
        }
            break;
            
        default:
            break;
    }
    
}



#pragma mark ------请求方法

/**
 *  发送GET请求
 *
 *  @param url       请求URL地址
 *  @param parameter 请求参数
 *  @param success   请求成功回调
 *  @param error     请求失败信息回调
 */
- (void)GET:(NSString *)url parameter:(id)parameter success:(void (^)(NSMutableDictionary *dict))success error:(void (^)(NSString *errorMsg))error{
    _manger = [AFHTTPSessionManager manager];
    
    //申明请求的格式JSON
//    _manger.requestSerializer=[AFJSONRequestSerializer serializer];
//    [_manger.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    //申明相应数据格式为JSON
//    _manger.responseSerializer = [AFJSONResponseSerializer serializer];
//    _manger.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/json"];
    
    [_manger GET:url parameters:parameter progress:nil success:^(NSURLSessionDataTask * _Nonnull task, NSDictionary *dict) {
        success(dict);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"失败信息：%@",error.description);
    }];
    
}

/**
 *  发送POST请求
 *
 *  @param url       请求URL地址
 *  @param parameter 请求参数
 *  @param success   请求成功回调
 *  @param error     请求失败信息回调
 */
- (void)POST:(NSString *)url parameter:(id)parameter success:(void (^)(NSMutableDictionary *dict))success error:(void (^)(NSString *errorMsg))error{
    _manger = [AFHTTPSessionManager manager];
    
    //申明请求的格式JSON
    _manger.requestSerializer=[AFJSONRequestSerializer serializer];
    [_manger.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    //申明相应数据格式为JSON
    _manger.responseSerializer = [AFJSONResponseSerializer serializer];
    _manger.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/json"];
    
    [_manger POST:url parameters:parameter progress:nil success:^(NSURLSessionDataTask * _Nonnull task, NSDictionary *dict) {
        success(dict);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"失败信息：%@",error.description);
    }];
    
    
}

/**
 *  发送PUT请求
 *
 *  @param url       请求URL地址
 *  @param parameter 请求参数
 *  @param success   请求成功回调
 *  @param error     请求失败信息回调
 */
- (void)PUT:(NSString *)url parameter:(id)parameter success:(void (^)(NSMutableDictionary *dict))success error:(void (^)(NSString *errorMsg))error{
    _manger = [AFHTTPSessionManager manager];
    
    //申明请求的格式JSON
    _manger.requestSerializer=[AFJSONRequestSerializer serializer];
    [_manger.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    //申明相应数据格式为JSON
    _manger.responseSerializer = [AFJSONResponseSerializer serializer];
    _manger.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/json"];
    
    [_manger PUT:url parameters:parameter success:^(NSURLSessionDataTask * _Nonnull task, NSDictionary *dict) {
        success(dict);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"失败信息：%@",error.description);
    }];
    
}

/**
 *  发送DELETE请求
 *
 *  @param url       请求URL地址
 *  @param parameter 请求参数
 *  @param success   请求成功回调
 *  @param error     请求失败信息回调
 */
- (void)DELETE:(NSString *)url parameter:(id)parameter success:(void (^)(NSMutableDictionary *dict))success error:(void (^)(NSString *errorMsg))error{
    _manger = [AFHTTPSessionManager manager];
    
    //申明请求的格式JSON
    _manger.requestSerializer=[AFJSONRequestSerializer serializer];
    [_manger.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    //申明相应数据格式为JSON
    _manger.responseSerializer = [AFJSONResponseSerializer serializer];
    _manger.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/json"];
    
    [_manger DELETE:url parameters:parameter success:^(NSURLSessionDataTask * _Nonnull task, NSDictionary *dict) {
        success(dict);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"失败信息：%@",error.description);
    }];
    
    
}

//以后做上传
- (void)UpLoad{
}

//以后做下载
- (void)DownLoad{
}

@end
